// #include "websocket_client.h"

// #include <iostream>

// int main(int argc,char **argv) {
//     std::cout<<"dfasdfasd"<<std::endl;
    
//     for(int i = 0; i < 500;i++) {
//         WebsocketClient *p = new WebsocketClient(false);
//         p->Connect("ws://127.0.0.1:9001/ws");

//     }
//     while(1) {
//         Sleep(1000);
        
//     }
//     return 0;
// }

#include <Windows.h>
#include <stdio.h>
#include <tchar.h>
#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

#define BUF_SIZE 4096

std::wstring String2WString(const std::string& str_in)
{
    if (str_in.empty())
    {
        std::cout << "str_in is empty" << std::endl;
        return L"";
    }
 
    // 获取待转换的数据的长度
    int len_in = MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)str_in.c_str(), -1, NULL, 0);
    if (len_in <= 0)
    {
        std::cout << "The result of WideCharToMultiByte is Invalid!" << std::endl;
        return L"";
    }
 
    // 为输出数据申请空间
    std::wstring wstr_out;
    wstr_out.resize(len_in - 1, L'\0');
 
    // 数据格式转换
    int to_result = MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)str_in.c_str(), -1, (LPWSTR)wstr_out.c_str(), len_in);
 
    // 判断转换结果
    if (0 == to_result)
    {
        std::cout << "Can't transfer String to WString" << std::endl;
    }
 
    return wstr_out;
}

std::vector<std::string> splitString(std::string srcStr, std::string delimStr,bool repeatedCharIgnored)
{
    std::vector<std::string> resultStringVector;
    std::replace_if(srcStr.begin(), srcStr.end(), [&](const char& c){if(delimStr.find(c)!=std::string::npos){return true;}else{return false;}}/*pred*/, delimStr.at(0));//将出现的所有分隔符都替换成为一个相同的字符（分隔符字符串的第一个）
    size_t pos=srcStr.find(delimStr.at(0));
    std::string addedString="";
    while (pos!=std::string::npos) {
        addedString=srcStr.substr(0,pos);
        if (!addedString.empty()||!repeatedCharIgnored) {
            resultStringVector.push_back(addedString);
        }
        srcStr.erase(srcStr.begin(), srcStr.begin()+pos+1);
        pos=srcStr.find(delimStr.at(0));
    }
    addedString=srcStr;
    if (!addedString.empty()||!repeatedCharIgnored) {
        resultStringVector.push_back(addedString);
    }
    return resultStringVector;
}

int StartProcessCommand(std::string path)
{
	HANDLE					PipeReadHandle;
	HANDLE					PipeWriteHandle;
	PROCESS_INFORMATION		ProcessInfo;
	SECURITY_ATTRIBUTES		SecurityAttributes;
	STARTUPINFO				StartupInfo;
	BOOL					Success;
 
    auto pos = path.find(".exe");
    if(pos != std::string::npos)
    {
        std::cout << "find it" << std::endl;
    }else{
        return -1;
    }

    auto tmp = splitString(path,"\\",true);
    std::string path1;
    for (auto itr = tmp.begin();itr != tmp.end();itr++){
        if(itr->find(".exe") == std::string::npos ){
            path1 += *itr +"\\";

        }
    }
	//--------------------------------------------------------------------------
	//	Zero the structures.
	//--------------------------------------------------------------------------
	ZeroMemory( &StartupInfo,			sizeof( StartupInfo ));
	ZeroMemory( &ProcessInfo,			sizeof( ProcessInfo ));
	ZeroMemory( &SecurityAttributes,	sizeof( SecurityAttributes ));
 
	//--------------------------------------------------------------------------
	//	Create a pipe for the child's STDOUT.
	//--------------------------------------------------------------------------
	SecurityAttributes.nLength              = sizeof(SECURITY_ATTRIBUTES);
	SecurityAttributes.bInheritHandle       = TRUE;
	SecurityAttributes.lpSecurityDescriptor = NULL;
 
	Success = CreatePipe
	(
		&PipeReadHandle,		// address of variable for read handle
		&PipeWriteHandle,		// address of variable for write handle
		&SecurityAttributes,	// pointer to security attributes
		0						// number of bytes reserved for pipe (use default size)
	);
 
	if ( !Success )
	{
		//ShowLastError(_T("Error creating pipe"));
		return -1;
	}	
 
	//--------------------------------------------------------------------------
	//	Set up members of STARTUPINFO structure.
	//--------------------------------------------------------------------------
	StartupInfo.cb           = sizeof(STARTUPINFO);
	StartupInfo.dwFlags      = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
	StartupInfo.wShowWindow  = SW_HIDE;
	StartupInfo.hStdOutput   = PipeWriteHandle;
	StartupInfo.hStdError    = PipeWriteHandle;
 
	//----------------------------------------------------------------------------
	//	Create the child process.
	//----------------------------------------------------------------------------
	Success = CreateProcessA
	( 
		NULL,					// pointer to name of executable module
		LPSTR(path.c_str()),	// command line 
		NULL,					// pointer to process security attributes 
		NULL,					// pointer to thread security attributes (use primary thread security attributes)
		TRUE,					// inherit handles
		0,						// creation flags
		NULL,					// pointer to new environment block (use parent's)
		path1.c_str(),	// pointer to current directory name
		&StartupInfo,			// pointer to STARTUPINFO
		&ProcessInfo			// pointer to PROCESS_INFORMATION
	);                 
 
	if ( !Success )
	{
		//ShowLastError(_T("Error creating process"));
		return -1;
	}
 
	DWORD	BytesLeftThisMessage = 0;
	DWORD	NumBytesRead;
    TCHAR	PipeData[BUF_SIZE] = {0}; 
	DWORD	TotalBytesAvailable = 0;
 
	for ( ; ; )
	{ 
		NumBytesRead = 0;
 
		Success = PeekNamedPipe
		( 
			PipeReadHandle,				// handle to pipe to copy from 
			PipeData,					// pointer to data buffer 
			1,							// size, in bytes, of data buffer 
			&NumBytesRead,				// pointer to number of bytes read 
			&TotalBytesAvailable,		// pointer to total number of bytes available
			&BytesLeftThisMessage		// pointer to unread bytes in this message 
		);
 
		if ( !Success )
		{
			break;
		}
 
		if ( NumBytesRead )
		{
			Success = ReadFile
			(
				PipeReadHandle,		// handle to pipe to copy from 
				PipeData,			// address of buffer that receives data
				BUF_SIZE - 1,		// number of bytes to read
				&NumBytesRead,		// address of number of bytes read
				NULL				// address of structure for data for overlapped I/O
			);
 
			if ( !Success )
			{
				break;
			}
 
			//------------------------------------------------------------------
			//	Zero-terminate the data.
			//------------------------------------------------------------------
			PipeData[NumBytesRead] = '\0';
 
			//------------------------------------------------------------------
			//	Replace backspaces with spaces.
			//------------------------------------------------------------------
			for ( DWORD ii = 0; ii < NumBytesRead; ii++ )
			{
				if ( PipeData[ii] == _T('\b') )
				{
					PipeData[ii] = ' ';
				}
			}
			
			//------------------------------------------------------------------
			//	If we're running a batch file that contains a pause command, 
			//	assume it is the last output from the batch file and remove it.
			//------------------------------------------------------------------
			TCHAR  *ptr = _tcsstr(PipeData, _T("Press any key to continue . . ."));
			if ( ptr )
			{
				*ptr = '\0';
			}
 

                // wstring data = String2WString(std::string(PipeData));
           
             std::cout << (PipeData);
		}
		else
		{
			//------------------------------------------------------------------
			//	If the child process has completed, break out.
			//------------------------------------------------------------------
			if ( WaitForSingleObject(ProcessInfo.hProcess, 0) == WAIT_OBJECT_0 )	//lint !e1924 (warning about C-style cast)
			{
				break;
			}
		}
		
	}
 
	//--------------------------------------------------------------------------
	//	Close handles.
	//--------------------------------------------------------------------------
	Success = CloseHandle(ProcessInfo.hThread);
	if ( !Success )
	{
	}
 
	Success = CloseHandle(ProcessInfo.hProcess);
	if ( !Success )
	{
	}
 
	Success = CloseHandle(PipeReadHandle);
	if ( !Success )
	{
	}
 
	Success = CloseHandle(PipeWriteHandle);
	if ( !Success )
	{
	}
}

int main(int argc, wchar_t* argv[])
{
    StartProcessCommand(std::string("G:\\project\\golang\\src\\background\\background.exe"));
}

